package com.wxzz.elearning.common.aop;

import com.alibaba.fastjson.JSONObject;
import com.wxzz.elearning.common.bean.OperationLogProducer;
import com.wxzz.elearning.common.dto.FeignOperationLogDto;
import com.wxzz.elearning.common.utils.IPUtils;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Aspect
@Component
public class ApiOperationAspect {

    @Autowired
    private OperationLogProducer operationLogProducer;

    @Pointcut("execution(* com.wxzz.elearing..*.*(..))")
    public void currentLimitingCut() {
    }

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @AfterReturning("currentLimitingCut()")
    public void around(JoinPoint joinPoint) {
        Class<?> clazz = joinPoint.getTarget().getClass();
        if (clazz != null) {
            RequestMapping classAnnotation = clazz.getAnnotation(RequestMapping.class);
            if (classAnnotation == null || classAnnotation.value()[0].contains("wx")) {
                return;
            }
        }

        FeignOperationLogDto feignOperationLogDto = new FeignOperationLogDto();
        String methodName = joinPoint.getSignature().getName();
        Method method = currentMethod(joinPoint, methodName);
        ApiOperation annotation = method.getAnnotation(ApiOperation.class);
        if (annotation != null) {
            if (annotation.value().contains("权限") || annotation.value().contains("登录")) {
                return;
            }
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String token = request.getHeader("token");
            if (StringUtils.isNotBlank(token)){
                JSONObject jsonObject = JSONObject.parseObject(redisTemplate.opsForValue().get(token));
                if (jsonObject != null) {
                    String ip = IPUtils.getIpAddr(request);
                    feignOperationLogDto.setIp(ip);
                    feignOperationLogDto.setAdminUserId(jsonObject.getLong("id"));
                    feignOperationLogDto.setOperationName(annotation.value());
                    operationLogProducer.ackMQSender(JSONObject.toJSONString(feignOperationLogDto));
                }
            }

        }
    }

    private Method currentMethod(JoinPoint joinPoint, String methodName) {
        /**
         * 获取目标类的所有方法，找到当前要执行的方法
         */
        Method[] methods = joinPoint.getTarget().getClass().getMethods();
        Method resultMethod = null;
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                resultMethod = method;
                break;
            }
        }
        return resultMethod;
    }
}
